Uurige, kuidas JavaScripti käivitamine mõjutab brauseri renderdamise torujuhtme iga etappi, ja õppige strateegiaid, kuidas optimeerida oma koodi veebi jõudluse ja kasutajakogemuse parandamiseks.
Brauseri renderdamise torujuhe: kuidas JavaScript mõjutab veebi jõudlust
Brauseri renderdamise torujuhe on järjestikused sammud, mida veebibrauser teeb, et muuta HTML-, CSS- ja JavaScripti kood visuaalseks esituseks kasutaja ekraanil. Selle torujuhtme mõistmine on ülioluline igale veebiarendajale, kes soovib ehitada suure jõudlusega veebirakendusi. JavaScript, olles võimas ja dünaamiline keel, mõjutab oluliselt selle torujuhtme iga etappi. See artikkel süveneb brauseri renderdamise torujuhtmesse ja uurib, kuidas JavaScripti käivitamine mõjutab jõudlust, pakkudes rakendatavaid optimeerimisstrateegiaid.
Brauseri renderdamise torujuhtme mõistmine
Renderdamise torujuhtme saab laias laastus jagada järgmisteks etappideks:- HTML-i parsistamine: Brauser parsib HTML-i märgistuse ja loob dokumendi objektimudeli (DOM), mis on puulaadne struktuur, mis esindab HTML-i elemente ja nende suhteid.
- CSS-i parsistamine: Brauser parsib CSS-i stiililehed (nii välised kui ka reasisesed) ja loob CSS-i objektimudeli (CSSOM), mis on teine puulaadne struktuur, mis esindab CSS-i reegleid ja nende omadusi.
- Kinnitamine: Brauser ühendab DOM-i ja CSSOM-i, et luua renderduspuu. Renderduspuu sisaldab ainult sisu kuvamiseks vajalikke sõlmi, jättes välja elemendid nagu <head> ja elemendid, millel on `display: none`. Igal nähtaval DOM-i sõlmel on vastavad CSSOM-i reeglid küljes.
- Paigutus (ümberarvutus): Brauser arvutab välja iga elemendi positsiooni ja suuruse renderduspuus. Seda protsessi tuntakse ka kui "ümberarvutus".
- Joonistamine (ümberjoonistamine): Brauser joonistab iga elemendi renderduspuus ekraanile, kasutades arvutatud paigutuse teavet ja rakendatud stiile. Seda protsessi tuntakse ka kui "ümberjoonistamine".
- Kompositsioon: Brauser ühendab erinevad kihid lõplikuks pildiks, mida ekraanil kuvada. Moodsad brauserid kasutavad kompositsiooni jaoks sageli riistvaralist kiirendust, mis parandab jõudlust.
JavaScripti mõju renderdamise torujuhtmele
JavaScript võib oluliselt mõjutada renderdamise torujuhet erinevates etappides. Halvasti kirjutatud või ebaefektiivne JavaScripti kood võib tekitada jõudluse kitsaskohti, mis toob kaasa aeglase lehe laadimise, tõmblevad animatsioonid ja kehva kasutajakogemuse.1. Parseri blokeerimine
Kui brauser puutub HTML-is kokku <script> sildiga, peatab see tavaliselt HTML-dokumendi parsistamise, et laadida alla ja käivitada JavaScripti kood. Seda seetõttu, et JavaScript võib muuta DOM-i ja brauser peab tagama, et DOM oleks enne jätkamist ajakohane. See blokeeriv käitumine võib oluliselt viivitada lehe esialgse renderdamisega.
Näide:
Kujutage ette stsenaariumi, kus teil on HTML-dokumendi <head> osas suur JavaScripti fail:
<!DOCTYPE html>
<html>
<head>
<title>Minu veebisait</title>
<script src="large-script.js"></script>
</head>
<body>
<h1>Tere tulemast minu veebisaidile!</h1>
<p>Siin on sisu.</p>
</body>
</html>
Sel juhul lõpetab brauser HTML-i parsistamise ja ootab, kuni `large-script.js` on alla laaditud ja käivitatud, enne kui renderdatakse elemendid <h1> ja <p>. See võib põhjustada märgatavat viivitust lehe esialgsel laadimisel.
Lahendused parseri blokeerimise minimeerimiseks:
- Kasutage atribuute `async` või `defer`: Atribuut `async` võimaldab skriptil alla laadida parserit blokeerimata ja skript käivitatakse kohe, kui see on alla laaditud. Atribuut `defer` võimaldab ka skriptil alla laadida parserit blokeerimata, kuid skript käivitatakse pärast HTML-i parsistamise lõpetamist järjekorras, nagu need HTML-is ilmuvad.
- Asetage skriptid <body> sildi lõppu: Asetades skriptid <body> sildi lõppu, saab brauser HTML-i parsida ja DOM-i ehitada enne skriptidega kokkupuutumist. See võimaldab brauseril lehe esialgse sisu kiiremini renderdada.
Näide kasutades `async`:
<!DOCTYPE html>
<html>
<head>
<title>Minu veebisait</title>
<script src="large-script.js" async></script>
</head>
<body>
<h1>Tere tulemast minu veebisaidile!</h1>
<p>Siin on sisu.</p>
</body>
</html>
Sel juhul laadib brauser faili `large-script.js` asünkroonselt alla, blokeerimata HTML-i parsistamist. Skript käivitatakse kohe, kui see on alla laaditud, potentsiaalselt enne kogu HTML-dokumendi parsistamist.
Näide kasutades `defer`:
<!DOCTYPE html>
<html>
<head>
<title>Minu veebisait</title>
<script src="large-script.js" defer></script>
</head>
<body>
<h1>Tere tulemast minu veebisaidile!</h1>
<p>Siin on sisu.</p>
</body>
</html>
Sel juhul laadib brauser faili `large-script.js` asünkroonselt alla, blokeerimata HTML-i parsistamist. Skript käivitatakse pärast kogu HTML-dokumendi parsistamise lõpetamist järjekorras, nagu see HTML-is ilmub.
2. DOM-i manipuleerimine
JavaScripti kasutatakse sageli DOM-i manipuleerimiseks, elementide ja nende atribuutide lisamiseks, eemaldamiseks või muutmiseks. Sagedased või keerulised DOM-i manipuleerimised võivad käivitada ümberarvutusi ja ümberjoonistamisi, mis on kulukad toimingud, mis võivad jõudlust oluliselt mõjutada.
Näide:
<!DOCTYPE html>
<html>
<head>
<title>DOM-i manipuleerimise näide</title>
</head>
<body>
<ul id="myList">
<li>Ese 1</li>
<li>Ese 2</li>
</ul>
<script>
const myList = document.getElementById('myList');
for (let i = 3; i <= 10; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Ese ${i}`;
myList.appendChild(listItem);
}
</script>
</body>
</html>
Selles näites lisab skript järjestamata loendisse kaheksa uut loendiüksust. Iga `appendChild` toiming käivitab ümberarvutuse ja ümberjoonistamise, kuna brauser peab paigutuse ümber arvutama ja loendi uuesti joonistama.
Lahendused DOM-i manipuleerimise optimeerimiseks:
- Minimeerige DOM-i manipuleerimisi: Vähendage DOM-i manipuleerimiste arvu nii palju kui võimalik. Selle asemel, et DOM-i mitu korda muuta, proovige muudatused kokku koguda.
- Kasutage DocumentFragment: Looge DocumentFragment, tehke kõik DOM-i manipuleerimised fragmendiga ja seejärel lisage fragment tegelikku DOM-i üks kord. See vähendab ümberarvutuste ja ümberjoonistamiste arvu.
- Vahemälu DOM-i elemente: Vältige sama elemendi jaoks DOM-i korduvat päringut. Salvestage elemendid muutujatesse ja kasutage neid uuesti.
- Kasutage tõhusaid selektoreid: Elementide sihtimiseks kasutage spetsiifilisi ja tõhusaid selektoreid (nt ID-sid). Vältige keerukate või ebaefektiivsete selektorite kasutamist (nt DOM-i puu unn vajalik läbimine).
- Vältige mittevajalikke ümberarvutusi ja ümberjoonistamisi: Teatud CSS-i omadused, nagu `width`, `height`, `margin` ja `padding`, võivad muutmise korral käivitada ümberarvutusi ja ümberjoonistamisi. Proovige vältida nende omaduste sagedast muutmist.
Näide DocumentFragmenti kasutamisega:
<!DOCTYPE html>
<html>
<head>
<title>DOM-i manipuleerimise näide</title>
</head>
<body>
<ul id="myList">
<li>Ese 1</li>
<li>Ese 2</li>
</ul>
<script>
const myList = document.getElementById('myList');
const fragment = document.createDocumentFragment();
for (let i = 3; i <= 10; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Ese ${i}`;
fragment.appendChild(listItem);
}
myList.appendChild(fragment);
</script>
</body>
</html>
Selles näites lisatakse kõik uued loendiüksused esmalt DocumentFragmenti ja seejärel lisatakse fragment järjestamata loendisse. See vähendab ümberarvutuste ja ümberjoonistamiste arvu ühe korrani.
3. Kulukad toimingud
Teatud JavaScripti toimingud on oma olemuselt kulukad ja võivad jõudlust mõjutada. Need hõlmavad järgmist:
- Keerulised arvutused: Keeruliste matemaatiliste arvutuste või andmetöötluse teostamine JavaScriptis võib kulutada märkimisväärseid protsessori ressursse.
- Suured andmestruktuurid: Suurte massiivide või objektidega töötamine võib suurendada mälukasutust ja aeglustada töötlemist.
- Regulaaravaldised: Keerukate regulaaravaldiste käivitamine võib olla aeglane, eriti suurte stringide korral.
Näide:
<!DOCTYPE html>
<html>
<head>
<title>Kulukas toimingu näide</title>
</head>
<body>
<div id="result"></div>
<script>
const resultDiv = document.getElementById('result');
let largeArray = [];
for (let i = 0; i < 1000000; i++) {
largeArray.push(Math.random());
}
const startTime = performance.now();
largeArray.sort(); // Kulukas toiming
const endTime = performance.now();
const executionTime = endTime - startTime;
resultDiv.textContent = `Täitmisaeg: ${executionTime} ms`;
</script>
</body>
</html>
Selles näites loob skript suure juhuslike arvude massiivi ja seejärel sorteerib selle. Suure massiivi sorteerimine on kulukas toiming, mis võib võtta märkimisväärselt aega.
Lahendused kulukate toimingute optimeerimiseks:
- Optimeerige algoritme: Kasutage tõhusaid algoritme ja andmestruktuure, et minimeerida vajaliku töötlemise hulka.
- Kasutage veebitöötajaid: Suunake kulukad toimingud veebitöötajatele, kes töötavad taustal ja ei blokeeri põhiteemat.
- Vahemälu tulemused: Vahemälu kulukate toimingute tulemused, et neid ei peaks iga kord uuesti arvutama.
- Debouncing ja Throttling: Rakendage debouncing või throttling tehnikaid, et piirata funktsioonide väljakutsete sagedust. See on kasulik sündmuste käsitlejatele, mida käivitatakse sageli, näiteks kerimissündmused või suuruse muutmise sündmused.
Näide veebitöötaja kasutamisega:
<!DOCTYPE html>
<html>
<head>
<title>Kulukas toimingu näide</title>
</head>
<body>
<div id="result"></div>
<script>
const resultDiv = document.getElementById('result');
if (window.Worker) {
const myWorker = new Worker('worker.js');
myWorker.onmessage = function(event) {
const executionTime = event.data;
resultDiv.textContent = `Täitmisaeg: ${executionTime} ms`;
};
myWorker.postMessage(''); // Käivitage töötaja
} else {
resultDiv.textContent = 'Veebitöötajad selles brauseris ei ole toetatud.';
}
</script>
</body>
</html>
worker.js:
self.onmessage = function(event) {
let largeArray = [];
for (let i = 0; i < 1000000; i++) {
largeArray.push(Math.random());
}
const startTime = performance.now();
largeArray.sort(); // Kulukas toiming
const endTime = performance.now();
const executionTime = endTime - startTime;
self.postMessage(executionTime);
}
Selles näites tehakse sorteerimistoiming veebitöötajas, mis töötab taustal ja ei blokeeri põhiteemat. See võimaldab kasutajaliidesel jääda reageerivaks, kui sorteerimine on pooleli.
4. Kolmanda osapoole skriptid
Paljud veebirakendused sõltuvad kolmanda osapoole skriptidest analüüsi, reklaami, sotsiaalmeedia integreerimise ja muude funktsioonide jaoks. Need skriptid võivad sageli olla märkimisväärne jõudluskulu allikas, kuna need võivad olla halvasti optimeeritud, laadida alla suures koguses andmeid või teostada kulukaid toiminguid.
Näide:
<!DOCTYPE html>
<html>
<head>
<title>Kolmanda osapoole skripti näide</title>
<script src="https://example.com/analytics.js"></script>
</head>
</body>
<h1>Tere tulemast minu veebisaidile!</h1>
<p>Siin on sisu.</p>
</body>
</html>
Selles näites laadib skript analüüsiskripti kolmanda osapoole domeenist. Kui selle skripti laadimine või käivitamine on aeglane, võib see lehe jõudlust negatiivselt mõjutada.
Lahendused kolmanda osapoole skriptide optimeerimiseks:
- Laadige skriptid asünkroonselt: Kasutage atribuute `async` või `defer`, et laadida kolmanda osapoole skriptid asünkroonselt, blokeerimata parserit.
- Laadige skriptid ainult siis, kui vaja: Laadige kolmanda osapoole skriptid ainult siis, kui neid tegelikult vaja on. Näiteks laadige sotsiaalmeedia vidinad ainult siis, kui kasutaja nendega suhtleb.
- Kasutage sisuedastusvõrku (CDN): Kasutage CDN-i kolmanda osapoole skriptide edastamiseks asukohast, mis on kasutajale geograafiliselt lähedal.
- Jälgige kolmanda osapoole skriptide jõudlust: Kasutage jõudluse jälgimise tööriistu, et jälgida kolmanda osapoole skriptide jõudlust ja tuvastada kõik kitsaskohad.
- Kaaluge alternatiive: Uurige alternatiivseid lahendusi, mis võivad olla suurema jõudlusega või mille jalajälg on väiksem.
5. Sündmuste kuulajad
Sündmuste kuulajad võimaldavad JavaScripti koodil reageerida kasutaja interaktsioonidele ja muudele sündmustele. Liiga paljude sündmuste kuulajate lisamine või ebaefektiivsete sündmuste käsitlejate kasutamine võib aga jõudlust mõjutada.
Näide:
<!DOCTYPE html>
<html>
<head>
<title>Sündmuse kuulaja näide</title>
</head>
<body>
<ul id="myList">
<li>Ese 1</li>
<li>Ese 2</li>
<li>Ese 3</li>
</ul>
<script>
const listItems = document.querySelectorAll('#myList li');
for (let i = 0; i < listItems.length; i++) {
listItems[i].addEventListener('click', function() {
alert(`Klõpsasite esemel ${i + 1}`);
});
}
</script>
</body>
</html>
Selles näites lisab skript igale loendiüksusele klõpsamissündmuse kuulaja. Kuigi see töötab, pole see kõige tõhusam lähenemisviis, eriti kui loend sisaldab suurt arvu üksusi.
Lahendused sündmuste kuulajate optimeerimiseks:
- Kasutage sündmuste delegeerimist: Selle asemel, et lisada sündmuste kuulajaid üksikutele elementidele, lisage üks sündmuste kuulaja vanemele elemendile ja kasutage sündmuste delegeerimist, et käsitleda sündmusi selle lastel.
- Eemaldage mittevajalikud sündmuste kuulajad: Eemaldage sündmuste kuulajad, kui neid enam vaja pole.
- Kasutage tõhusaid sündmuste käsitlejaid: Optimeerige kood oma sündmuste käsitlejate sees, et minimeerida vajaliku töötlemise hulka.
- Drosseldage või eemaldage sündmuste käsitlejad: Kasutage drosseldamise või eemaldamise tehnikaid, et piirata sündmuste käsitleja väljakutsete sagedust, eriti sündmuste korral, mida käivitatakse sageli, näiteks kerimissündmused või suuruse muutmise sündmused.
Näide sündmuste delegeerimise kasutamisega:
<!DOCTYPE html>
<html>
<head>
<title>Sündmuse kuulaja näide</title>
</head>
<body>
<ul id="myList">
<li>Ese 1</li>
<li>Ese 2</li>
<li>Ese 3</li>
</ul>
<script>
const myList = document.getElementById('myList');
myList.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
const index = Array.prototype.indexOf.call(myList.children, event.target);
alert(`Klõpsasite esemel ${index + 1}`);
}
});
</script>
</body>
</html>
Selles näites on järjestamata loendisse lisatud üks klõpsamissündmuse kuulaja. Kui klõpsatakse loendiüksusel, kontrollib sündmuse kuulaja, kas sündmuse sihtmärk on loendiüksus. Kui see on nii, käsitleb sündmuse kuulaja sündmust. See lähenemisviis on tõhusam kui igale loendiüksusele klõpsamissündmuse kuulaja lisamine eraldi.
Tööriistad JavaScripti jõudluse mõõtmiseks ja parandamiseks
JavaScripti jõudluse mõõtmiseks ja parandamiseks on saadaval mitu tööriista:- Brauseri arendustööriistad: Moodsates brauserites on sisseehitatud arendustööriistad, mis võimaldavad teil JavaScripti koodi profileerida, tuvastada jõudluse kitsaskohti ja analüüsida renderdamise torujuhet.
- Lighthouse: Lighthouse on avatud lähtekoodiga automatiseeritud tööriist veebilehtede kvaliteedi parandamiseks. Sellel on auditid jõudluse, juurdepääsetavuse, progressiivsete veebirakenduste, SEO ja muu jaoks.
- WebPageTest: WebPageTest on tasuta tööriist, mis võimaldab teil testida oma veebisaidi jõudlust erinevatest asukohtadest ja brauseritest.
- PageSpeed Insights: PageSpeed Insights analüüsib veebilehe sisu ja genereerib seejärel soovitusi selle lehe kiiremaks muutmiseks.
- Jõudluse jälgimise tööriistad: Saadaval on mitu kaubanduslikku jõudluse jälgimise tööriista, mis aitavad teil jälgida oma veebirakenduse jõudlust reaalajas.
Järeldus
JavaScript mängib brauseri renderdamise torujuhtmes üliolulist rolli. Arusaamine, kuidas JavaScripti käivitamine jõudlust mõjutab, on oluline suure jõudlusega veebirakenduste ehitamiseks. Järgides selles artiklis kirjeldatud optimeerimisstrateegiaid, saate minimeerida JavaScripti mõju renderdamise torujuhtmele ja pakkuda sujuvat ja reageerivat kasutajakogemust. Pidage meeles, et alati mõõtke ja jälgige oma veebisaidi jõudlust, et tuvastada ja kõrvaldada kõik kitsaskohad.
See juhend annab kindla aluse JavaScripti mõju mõistmiseks brauseri renderdamise torujuhtmele. Jätkake nende tehnikate uurimist ja katsetamist, et täiustada oma veebiarendusoskusi ja luua erakordseid kasutajakogemusi ülemaailmsele publikule.